package com.mallbook.model.service;

import com.mallbook.controller.servlet.front.UserServlet;
import com.mallbook.model.exception.AddressNoException;
import com.mallbook.model.exception.GoodsStockNotException;
import com.mallbook.model.exception.ServiceException;
import com.mallbook.model.pojo.*;
import com.mallbook.model.mapper.AddressMapper;
import com.mallbook.model.mapper.GoodsMapper;
import com.mallbook.model.mapper.OrdersDetailsMapper;
import com.mallbook.model.mapper.OrdersMapper;

import com.mallbook.model.utils.MybatisUtils;
import org.apache.ibatis.exceptions.PersistenceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.mail.Session;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author 宋明松
 * @Version V1.0.0
 * @Date 2022-06-25
 * 订单service层
 */
public class OrderService {
    private static final Logger logger = LoggerFactory.getLogger(OrderService.class);

    /**
     * 新增订单
     *
     * @param ordersDetailsList 订单详情集合
     */
    public synchronized int addOrders(Integer uId, Integer payMethod, Orders subOrders, List<OrdersDetails> ordersDetailsList) {
        OrdersMapper ordersMapper = MybatisUtils.getMappers(OrdersMapper.class);
        AddressMapper addressMapper = MybatisUtils.getMappers(AddressMapper.class);
        OrdersDetailsMapper ordersDetailsMapper = MybatisUtils.getMappers(OrdersDetailsMapper.class);
        GoodsMapper goodsMapper = MybatisUtils.getMappers(GoodsMapper.class);
        // 下单时间：系统当前时间
        LocalDateTime date = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String setTime = formatter.format(date);
        logger.info("用户{}开始下单:", uId);
        // 订单金额合计：需要从订单详情里取出金额计算
        BigDecimal totalMoney = new BigDecimal("0");
        for (OrdersDetails o : ordersDetailsList
        ) {
            // 商品数量
            BigDecimal bookNum = new BigDecimal(o.getBookNums().toString());
            logger.info("商品数量{}:", bookNum);
            // 查询该商品的价格并计算
            BigDecimal bookPrice = bookNum.multiply(goodsMapper.findGoodsById(o.getBookId()).getSellingPrice());
            logger.info("商品总价格{}:", bookPrice);
            // 获取数据库中的库存
            try {
                Goods DBGoods = goodsMapper.findGoodsById(o.getBookId());
                int stock = DBGoods.getStock();
                // 销量增加
                int salesNum = DBGoods.getSalesNum();
                logger.info("商品库存{}:", bookPrice);
                // 减少后的库存
                int flagStock = stock - o.getBookNums();
                // 增加后的销量
                int flagSalesNum = salesNum + o.getBookNums();
                logger.info("商品剩余库存{}:", bookPrice);
                logger.info("商品增加后的销量{}:", flagSalesNum);
                // 库存不足
                if (flagStock < 0) {
                    logger.info("错误:", "库存不足");
                    throw new GoodsStockNotException(o.getBookNums() + "：库存不足");
                }
                Goods goods = new Goods();
                goods.setStock(flagStock);
                goods.setSalesNum(flagSalesNum);
                goodsMapper.update(goods, o.getBookId());
                // 计算总金额
                totalMoney = totalMoney.add(bookPrice);
                logger.info("下单总金额{}", totalMoney);
            } catch (
                    PersistenceException e) {
                throw new ServiceException("数据操作异常", e);
            }
        }
        // 订单编号：使用当前时间戳拼接
        String orderNumber = "mallBook-" + System.currentTimeMillis();
        logger.info("订单编号{}", orderNumber);
        int orderID = 0;
        try {
            // 查询该用户所拥有的地址数量
            int addressNums = addressMapper.findAddressBySumNum(uId);
            if (addressNums == 0) {
                throw new AddressNoException("用户还没有收货地址");
            }
            // 查询默认收货地址
            Address defaultAddress = addressMapper.findDefaultAddress(uId);

            Orders orders = new Orders();
            User user = new User();
            user.setId(uId);
            orders.setUser(user);
            orders.setOrdersId(orderNumber);
            orders.setTimes(setTime);
            orders.setConSingnee(subOrders.getConSingnee());
            orders.setAddress(subOrders.getAddress());
            orders.setTel(subOrders.getTel());
            orders.setPayMethod(payMethod);
            orders.setState(1);
            orders.setTotalMoney(totalMoney);
            // 添加订单到数据库
            ordersMapper.add(orders);
            // 获取该订单ID
            orderID = orders.getId();
            logger.info("订单ID{}", orderID);
            // 添加订单详情信息
            for (OrdersDetails o : ordersDetailsList
            ) {
                o.setOrderId(orderID);
                // 查询该商品的价格并设置
                o.setPrice(goodsMapper.findGoodsById(o.getBookId()).getSellingPrice());
                ordersDetailsMapper.add(o);
            }
        } catch (
                PersistenceException e) {
            logger.error("新增订单数据操作异常{}", e);
            throw new ServiceException("数据操作异常", e);
        }
        return orderID;
    }

    /**
     * 查询所有订单
     *
     * @return
     */
    public PageBean<Orders> getAllOrders(Integer page) {
        return PageBeanOrders.getByPage(null, null, page);
    }

    /**
     * 查看订单信息
     *
     * @param id 订单ID
     * @return
     */
    public Orders getOrdersById(Integer id) {
        OrdersMapper ordersMapper = MybatisUtils.getMappers(OrdersMapper.class);
        try {
            return ordersMapper.findOrdersById(id);
        } catch (
                PersistenceException e) {
            logger.error("查看订单信息数据操作异常{}", e);
            throw new ServiceException("数据操作异常", e);
        }
    }

    /**
     * 多条件查询
     * <p>
     * 如果是用户，需要传入用户ID
     * 如果是管理员，user=null
     *
     * @param orders 需要查询的信息
     * @param user   用户信息
     * @return
     */
    public PageBean<Orders> getOrdersByCondition(Orders orders, User user, Integer page) {
        return PageBeanOrders.getByPage(orders, user, page);
    }

    /**
     * 根据用户id分页查询订单，查询详情
     *
     * @param uId 用户ID
     * @return
     */
    public PageBean<Orders> getOrdersByUid(Integer uId, Integer page) {

        User user = new User();
        user.setId(uId);
        return PageBeanOrders.getByPage(null, user, page);
    }

    /**
     * 修改发货时间
     * 管理员
     *
     * @param id 订单ID
     */
    public void updateOrdersStartTime(Integer id) {
        OrdersMapper ordersMapper = MybatisUtils.getMappers(OrdersMapper.class);
        // 下单时间：系统当前时间
        LocalDateTime date = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String setTime = formatter.format(date);
        Orders orders = new Orders();
        orders.setStartTime(setTime);
        orders.setState(3);
        orders.setId(id);
        try {
            ordersMapper.update(orders, null);
        } catch (
                PersistenceException e) {
            throw new ServiceException("数据操作异常", e);
        }
    }

    /**
     * 确认收货时间
     * 用户
     *
     * @param oId 订单ID
     * @param uId 订单ID
     */
    public void updateOrdersEndTime(Integer oId, Integer uId) {
        OrdersMapper ordersMapper = MybatisUtils.getMappers(OrdersMapper.class);
        // 确认收货时间：系统当前时间
        LocalDateTime date = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String setTime = formatter.format(date);
        Orders orders = new Orders();
        orders.setEndTime(setTime);
        orders.setId(oId);
        orders.setState(4);
        try {
            ordersMapper.update(orders, uId);
        } catch (
                PersistenceException e) {
            throw new ServiceException("数据操作异常", e);
        }
    }

    /**
     * 修改订单状态
     *
     * @param orderState
     */
    public void updateOrderState(int orderState, int oid, Integer uid) {
        OrdersMapper ordersMapper = MybatisUtils.getMappers(OrdersMapper.class);
        Orders orders = new Orders();
        orders.setState(orderState);
        orders.setId(oid);
        try {
            ordersMapper.update(orders, uid);
        } catch (
                PersistenceException e) {
            throw new ServiceException("数据操作异常", e);
        }
    }

    /**
     * 修改订单信息
     *
     * @param shr   收货人
     * @param shdz  收货地址
     * @param tel   电话号码
     * @param ddje  订单金额
     * @param state 订单状态
     * @param oid   订单ID
     */
    public void update(String shr, String shdz, String tel, String ddje, Integer state, Integer oid) {
        OrdersMapper ordersMapper = MybatisUtils.getMappers(OrdersMapper.class);
        Orders orders = new Orders();
        orders.setState(state);
        orders.setTotalMoney(new BigDecimal(ddje));
        orders.setTel(tel);
        orders.setAddress(shdz);
        orders.setConSingnee(shr);
        orders.setId(oid);
        try {
            ordersMapper.update(orders, null);
        } catch (
                PersistenceException e) {
            throw new ServiceException("数据操作异常", e);
        }
    }

    /**
     * 获取最新订单
     *
     * @param size 获取最新订单的数量
     * @return
     */
    public List<Orders> getNewOrders(int size) {
        OrdersMapper ordersMapper = MybatisUtils.getMappers(OrdersMapper.class);
        try {
            return ordersMapper.findNewOrders(size);
        } catch (
                PersistenceException e) {
            throw new ServiceException("数据操作异常", e);
        }
    }

    /**
     * 删除订单
     *
     * @param uid
     * @param oid
     */
    public void delOrder(Integer uid, Integer oid) {
        try {
            OrdersMapper ordersMapper = MybatisUtils.getMappers(OrdersMapper.class);
            ordersMapper.delete(oid, uid);
        } catch (
                PersistenceException e) {
            throw new ServiceException("数据操作异常", e);
        }
    }

    /**
     * 返回一个String类型的数组，
     * 索引：
     * 0：订单总数；1：订单总金额；2：待评价订单数；3：代付款订单数；4：待确认收货订单数
     *
     * @param uid
     * @return
     */
    public String[] getUcenterOrderDetailNums(Integer uid) {
        OrdersMapper ordersMapper = MybatisUtils.getMappers(OrdersMapper.class);
        Integer allOrderNums = 0;
        BigDecimal allMoney = new BigDecimal("0");
        Integer notEvaluateNums = 0; // 待评价订单
        Integer notGetMoneyNums = 0; // 代付款订单
        Integer notConfirmNums = 0; // 待确认收货订单
        List<UcenterOrderInfo> ucenterOrderInfoList = ordersMapper.findUcenterOrderInfos(uid);
        for (UcenterOrderInfo u : ucenterOrderInfoList
        ) {
            allOrderNums += u.getAllOrderNums();
            allMoney = allMoney.add(u.getAllMoney());
            if (u.getState() == 4) {
                notEvaluateNums = u.getAllOrderNums();
            }
            if (u.getState() == 1) {
                notGetMoneyNums = u.getAllOrderNums();
            }
            if (u.getState() == 3 || u.getState() == 2) {
                notConfirmNums = u.getAllOrderNums();
            }
        }
        System.out.println(notEvaluateNums);
        System.out.println(notGetMoneyNums);
        System.out.println(notConfirmNums);
        String[] info = new String[5];
        info[0] = String.valueOf(allOrderNums);
        info[1] = String.valueOf(allMoney);
        info[2] = String.valueOf(notEvaluateNums);
        info[3] = String.valueOf(notGetMoneyNums);
        info[4] = String.valueOf(notConfirmNums);
        return info;
    }
}
